<?php
namespace app\components;
use Yii;
  require(dirname(__FILE__).'/Excel/PHPExcel.php');
class BaseExcelList{
   public static $STATIC_SELF=false;


   /**
     * Excel表格对象
    */
   private $PHP_EXCEL=null;
   /**
    * base表格对象
   */
  private $Base=null;
  
  /**
   * 列信息
  */
 private $topList=[];

 /**
  * 为数据分页,设置数据最大行数
 */
const PageMax=65535;//65535/////因为Excel最大行数为65536所以这里最多不能超过65535


/**
 * 每条输出行后面附加的信息
*/
private $_echo_msg='';
/**
     * 加载表格类实例
    */
   public function load($baselist){
       self::$STATIC_SELF=$this;
       $this->Base=$baselist;
       $this->P('开始加载表格程序');
       @ini_set('memory_limit', '5900M');
      
      $this->P('加载成功,开始处理');
       //$resultPHPExcel =$this->PHP_EXCEL;
      $count=$this->Base->find()->count();
      $allPage=(int)(($count-1)/self::PageMax);
      $this->P('当前查询到'.$count.'条记录,需要分'.($allPage+1).'批导出,每批有记录为:'.self::PageMax);
      for($p=0;$p<=$allPage;$p++){
          $this->_echo_msg='第{'.($p+1).'/'.($allPage+1).'}批';
         $this->savePage($p);   
       //  sleep(10000);
      } 
      $this->P("本次导出结束");
   }
   
   /**
    * 保存分页数据
   */
   private function savePage($page){
       
        $this->PHP_EXCEL=new \PHPExcel(); 
       unset($this->BaseListAll);
     $this->BaseListAll=  
                $this->Base->find()
               ->offset($page*self::PageMax)
               ->limit(self::PageMax)
               ->all();
       
         $this->title();////显示标题部分
        $this->content(); 
         $this->save($page);
         unset($this->PHP_EXCEL);
   }
   /**
    * 从数据库读取的数据,改程序的任务就是把这部分的数据显示出来
   */
   private $BaseListAll=[];


   /**
    * 表格内容
   */
  private function content(){
      $this->P('开始读取数据库');
     
    ///  $list=  $this->Base->find()->all();
    $list=  $this->BaseListAll;
     /// echo count($list);exit;
      $length=count($list);
      $this->P('读取数据库完成,开始处理表格内容部分');
      $this->Base->ExceLabels();
      //print_r($this->topList);exit;
      $hang=2;
      foreach ($list as $vo) {
          foreach ($this->topList as $key=>$lie) {
              $val=  $this->Base->ModelTohtml($key,$vo);
              $this->PHP_EXCEL->getActiveSheet()->setCellValue($lie . $hang,$val);
          }
          $hang++;
          $wc=(int)(($hang-2)/$length*100);
          $this->P('完成度:'.$wc.'%');
          
      }
      $this->P('表格处理完成');
  }

  



  /**
    * 显示标题部分
   */
  private function title(){
    $this->P('读取标题');
    $resultPHPExcel =$this->PHP_EXCEL;
    $lab=$this->Base->ExceLabels();
    $tl=0;
    foreach ($lab as $key=>$vo) {
        
        $zm=$this->get_char($tl);
     //  var_dump($tl); var_dump($zm);exit;
         $resultPHPExcel->getActiveSheet()->setCellValue($zm.'1',$vo);
         $tl++;
         $this->topList[$key]=$zm;
    }
    $this->P('读取标题完成');
  }

    
   
   
   
   /**
    * 保存导出程序
   */
  public function save($page){
      $this->P('进入保存文件阶段,开始保存');
        $xlsWriter = new \PHPExcel_Writer_Excel5($this->PHP_EXCEL); 
        $outputFileName = $this->Base->get_model()->tableName().date("His",time()).'{'.$page.'}.xls';
         if($this->Base->echo_Save){ //输出方式,如果为true为保存,否则为下载  
           $outputFileName=  Yii::$app->runtimePath.'/'.$outputFileName;
           $xlsWriter->save($outputFileName); 
           $this->P('保存完成,文件名:'.$outputFileName);
            $this->P('完成');return;//exit;
        }
                 
          header("Content-Type: application/force-download");
        header("Content-Type: application/octet-stream");
        header("Content-Type: application/download");
        header('Content-Disposition:inline;filename="' . $outputFileName . '"');
        header("Content-Transfer-Encoding: binary");
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Pragma: no-cache");
       
        $xlsWriter->save("php://output"); 
       
  }
  
   /**
     * 根据数值id返回字符串kid
     * ID的最大值是PHP_INT_MAX=2147483647
     *
     * $len表示生成的长度,如果不足这个长度则用0补充,如果为0,则不考虑长度
     * 默认为4位
    */
   private function get_char($id) {
       $char_len=0;
        $char = [ //'',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
            'I', 
            'J', 'K', 
           'L',
            'M', 'N',
             'O', 
            'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
        ];
     //   $char=['0','1','2','3','4','5', '6', '7', '8',];
        
        $len = count($char);
        $id = (INT) $id; 
        if($id===0){
            return  $char[0];
        }
        $str = '';
       // var_dump( $char[$id %$len]);
      //  exit($len);
        for (; $id != -1;) {
             
           $str = $char[$id %$len] . $str; //;echo ' ';
            $id = (INT) ($id / $len)-1;
        }        
        if($char_len===0){
            return $str;
        }        
        $char_xc=$char_len-strlen($str);
        if($char_xc<=0){
            return $str;
        }
        return str_pad($str, $char_len,$char[0],STR_PAD_LEFT);        
    }
  
  /**
   * 判断是否为window系统
    */
   private function isWin(){
       static $win=null;
       if($win===null){
            $isWind=strtoupper(substr(PHP_OS,0,3)=='WIN');
           if($isWind){
               $win=true;
           }else{
               $win=false;
           }
       }
       return $win;
   }
   /**
    * 为了避免重复输出
   */
   private $_echo_p='';

   /**
   * 输出文字
    */
    public  function P($text){
       //  return;
       if(!$this->Base->echo_Save){
            return;
        }
        if($this->_echo_p===$text){
            return;
        }
        $this->_echo_p=$text;
        
        $text.="\t".$this->_echo_msg;
         if($this->isWin()){
             $text=iconv("UTF-8", "GB2312", $text); 
         }
        
        echo $text."\r\n";
    }
  
  
  
}